﻿
using Txt2Shp4Sharp.landm;
using Txt2Shp4Sharp.lib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Txt2Shp4Sharp.FormView
{
    public partial class FormTxt2Shp : Form
    {
        private GlobalApplication m_pluginApplication = null;
        private string m_InputTxtPath = "";  //txt输入路径
        private string m_outputShpPath = ""; //shp输出路径
        public FormTxt2Shp()
        {
            InitializeComponent();
        }
        public FormTxt2Shp(GlobalApplication pluginApplication)
        {
            InitializeComponent();
            this.m_pluginApplication = pluginApplication;
        }

        private void btnTxt2Shp_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.Button btn = (System.Windows.Forms.Button)sender;
            String btnName = btn.Name;
            switch (btnName)
            {
                case "btnTxt2Shp_outputpath": //shp输出目录
                    //输入路径（文件夹）
                    m_outputShpPath = "";
                    FolderBrowserDialog shpPathDialog = new FolderBrowserDialog();
                    shpPathDialog.Description = "请选择待输出的Shp路径";
                    if (shpPathDialog.ShowDialog() == DialogResult.OK)
                    {
                        m_outputShpPath = shpPathDialog.SelectedPath;
                    }

                    if (m_outputShpPath == String.Empty)
                    {
                        return;
                    }

                    this.textBox_outputShpPath.Text = m_outputShpPath;

                    this.listBox1.Items.Add("  ");
                    this.listBox1.Items.Add(String.Format("-->Shp文件输出路径：{0}", m_outputShpPath));

                    break;

                case "btnTxt2Shp_inputBrowse": //txt输入目录
                    //输入路径（文件夹）
                    m_InputTxtPath = "";
                    FolderBrowserDialog txtPathDialog = new FolderBrowserDialog();
                    txtPathDialog.Description = "请选择待转换的Txt文件输入路径";
                    if (txtPathDialog.ShowDialog() == DialogResult.OK)
                    {
                        m_InputTxtPath = txtPathDialog.SelectedPath;
                    }

                    if (m_InputTxtPath == String.Empty)
                    {
                        return;
                    }

                    this.textBox_inputTxtPath.Text = m_InputTxtPath;
                    this.listBox1.Items.Add("  ");
                    this.listBox1.Items.Add(String.Format("-->Txt文件输入路径：{0}", m_InputTxtPath));

                    //待处理的Txt文件列表
                    this.listView1.Items.Clear();
                    this.ListTxtFile(m_InputTxtPath);

                    break;

                case "btnTxt2Shp_Convert": //开始转换
                    if (m_InputTxtPath == null || m_outputShpPath == null || this.listView1.Items.Count == 0)
                    {
                        return;
                    }

                    DateTime dateNow = DateTime.Now;
                    this.listBox1.Items.Add("  ");
                    this.listBox1.Items.Add(String.Format("-->开始Txt2Shp的转换：{0}", dateNow.ToString()));
                    //转换为shp，并添加到地图中
                    List<String> shpfileList =  txt2shp4_bat(YwType.tdgy, m_InputTxtPath, m_outputShpPath);
                    for (int i = 0; i < shpfileList.Count; i++)
                    {
                        String shpfilePath = shpfileList[i];
                        m_pluginApplication.addLayerByPath(shpfilePath);
                    }
                    /*
                    IMxDocument pMxDocument = (IMxDocument)m_pluginApplication.ArcMapApplication.Document;
                    ESRI.ArcGIS.Carto.IActiveView pActiveView = pMxDocument.ActivatedView;
                    pActiveView.Extent = pActiveView.FullExtent;
                    pActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeography, null, null);
                    */

                    break;
            }
        }

        private void ListTxtFile(string inputDir)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(inputDir);
            //文件
            var files = dirInfo.GetFiles();
            int xh = 0;
            foreach (var file in files)
            {
                string srcPath = file.FullName;
                if (Path.GetExtension(srcPath) == ".txt")
                {
                    xh++;
                    this.listView1.Items.Add(new ListViewItem(new string[] { xh.ToString(), srcPath }));
                }
            }

            //文件夹-递归调用
            var subDirInfos = dirInfo.GetDirectories();
            foreach (var subDirInfo in subDirInfos)
            {
                string srcPath = subDirInfo.FullName;
                ListTxtFile(srcPath);
            }
        }

        public List<String> txt2shp4_bat(YwType ywtype, String txtfolder, String outpath)
        {
            List<String> shpfileList = new List<string>();

            String encoding = "GBK";
            //String encoding = "utf-8";
            //1-设置路径
            //String txtfolder = "D:\\temp\\dhtool\\永川坐标串\\永川权益科";
            //String outfilepath = "D:\\temp\\dhtool\\永川坐标串";
            String qxmc = "cq2";
            //tip: 划拨、出让、未知、补充、其他
            String tdgyfs = "cgcs2000";

            //2-坐标系与投影定义
            //EPSG:4496  CGCS2000 / 3-degree Gauss-Kruger zone 18
            String wkt18 = "PROJCS[\"CGCS2000_Gauss_Kruger_zone_18\",GEOGCS[\"GCS_China Geodetic Coordinate System 2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137,298.257222101]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",105],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",18500000],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]";
            //EPSG:4523  CGCS2000 / 3-degree Gauss-Kruger zone 35
            String wkt35 = "PROJCS[\"CGCS2000_3_degree_Gauss_Kruger_zone_35\",GEOGCS[\"GCS_China Geodetic Coordinate System 2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137,298.257222101]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",105],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",35500000],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]";
            //EPSG:4524  CGCS2000 / 3-degree Gauss-Kruger zone 36
            String wkt36 = "PROJCS[\"CGCS2000_3_degree_Gauss_Kruger_zone_36\",GEOGCS[\"GCS_China Geodetic Coordinate System 2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137,298.257222101]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",108],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",36500000],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]";
            //EPSG:4525  CGCS2000 / 3-degree Gauss-Kruger zone 37
            String wkt37 = "PROJCS[\"CGCS2000_3_degree_Gauss_Kruger_zone_37\",GEOGCS[\"GCS_China Geodetic Coordinate System 2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137,298.257222101]],PRIMEM[\"Greenwich\",0],UNIT[\"Degree\",0.017453292519943295]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",111],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",37500000],PARAMETER[\"false_northing\",0],UNIT[\"Meter\",1]]";
            //重庆主城独立坐标
            String wktcqdl = "PROJCS[\"CQDULI\",GEOGCS[\"GCS_Beijing_1954\",DATUM[\"D_Beijing_1954\",SPHEROID[\"Krasovsky_1940\",6378245.0,298.3]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gauss_Kruger\"],PARAMETER[\"False_Easting\",50000.0],PARAMETER[\"False_Northing\",-3202855.272],PARAMETER[\"Central_Meridian\",106.419263889],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]";

            //3-加载所有txt
            DirectoryInfo txtInputDirInfo = new DirectoryInfo(txtfolder);
            Dictionary<String, Land> allLands = new Dictionary<String, Land>();

            System.Console.WriteLine();
            System.Console.WriteLine("---------------第1步,正在将txt转换为Land对象中------------------");
            this.listBox1.Items.Add("  ");
            this.listBox1.Items.Add("---------------第1步,正在将txt转换为Land对象中------------------");
            int iNum = 0;
            FileInfo[] fs = txtInputDirInfo.GetFiles();
            foreach (var f in fs)
            {
                string txtfile = f.FullName;
                if (Path.GetExtension(txtfile) == ".txt"){
                    iNum++;

                    System.Console.WriteLine("第 " + iNum + " 个txt转换Land对象-------------------------");
                    try
                    {
                        String fileNameNoExt = System.IO.Path.GetFileNameWithoutExtension(txtfile);  //文件名称，一般是DZJGH或者PZWH
                        
                        //重要，解析坐标串文件为Land对象
                        Land land = Land.readTxtFile2(txtfile, encoding);
                        if (land != null){
                            //按照txt文件名为key进行存储
                            allLands.Add(fileNameNoExt, land);

                            System.Console.WriteLine("--->解析txt文本内容成功：" + fileNameNoExt);
                            this.listBox1.Items.Add("--->解析txt文本内容成功：" + fileNameNoExt);
                        }
                        else {
                            System.Console.WriteLine("--->解析txt文本内容失败：" + fileNameNoExt);
                            this.listBox1.Items.Add("--->解析txt文本内容失败：" + fileNameNoExt);
                        }
                    }
                    catch (Exception ex)
                    {
                        string msg = ex.Message;
                        System.Console.WriteLine("--->异常：" + msg);
                    }
                    
                }
            }

            //4-拆分到3个分度带
            System.Console.WriteLine();
            System.Console.WriteLine("---------------第2步,正在对Land对象不同度带(35,36,37)分析拆分中------------------");
            this.listBox1.Items.Add("  ");
            this.listBox1.Items.Add("---------------第2步,正在对Land对象不同度带(35,36,37)分析拆分中------------------");
            Dictionary<String, Dictionary<String, Land>> allDegreeLands = new Dictionary<String, Dictionary<String, Land>>();

            Dictionary<String, Land> degree18Lands = new Dictionary<String, Land>();
            Dictionary<String, Land> degree35Lands = new Dictionary<String, Land>();
            Dictionary<String, Land> degree36Lands = new Dictionary<String, Land>();
            Dictionary<String, Land> degree37Lands = new Dictionary<String, Land>();
            Dictionary<String, Land> degreeCqdlLands = new Dictionary<String, Land>();

            //6-遍历所有Land对象，并通过度带号加入到不同的度带集合中
            Dictionary<String, Land>.Enumerator dzjghSetEnumertor = allLands.GetEnumerator();
            while (dzjghSetEnumertor.MoveNext())
            {
                KeyValuePair<String, Land> kvp = dzjghSetEnumertor.Current;

                String dzjgh = kvp.Key;
                Land land = kvp.Value;

                //根据度带号判断
                if ("18" == land.DegreeNum)
                {
                    degree18Lands.Add(dzjgh, land);
                }
                else if ("35" == land.DegreeNum)
                {
                    degree35Lands.Add(dzjgh, land);
                }
                else if ("36" == land.DegreeNum)
                {
                    degree36Lands.Add(dzjgh, land);
                }
                else if ("37" == land.DegreeNum)
                {
                    degree37Lands.Add(dzjgh, land);
                }
                else if ("cqdl" == land.DegreeNum)
                {
                    degreeCqdlLands.Add(dzjgh, land);
                }
            }


            if (degree18Lands.Count > 0)
            {
                allDegreeLands.Add("18", degree18Lands);
            }
            if (degree35Lands.Count > 0)
            {
                allDegreeLands.Add("35", degree35Lands);
            }
            if (degree36Lands.Count > 0)
            {
                allDegreeLands.Add("36", degree36Lands);
            }
            if (degree37Lands.Count > 0)
            {
                allDegreeLands.Add("37", degree37Lands);
            }
            if (degreeCqdlLands.Count > 0)
            {
                allDegreeLands.Add("cqdl", degreeCqdlLands);
            }

            //7-定义字段内容
            String geometryType = "esriGeometryPolygon";
            String fields = "";
            Dictionary<String, String> fieldInfos = new Dictionary<string, string>();
            if (ywtype == YwType.tdzs)
            {
                fields = "["
                        + "{\"name\":\"qxdm\",\"type\":\"esriFieldTypeString\",\"alias\":\"qxdm\"},"
                        + "{\"name\":\"jsscbh\",\"type\":\"esriFieldTypeString\",\"alias\":\"jsscbh\"},"
                        + "{\"name\":\"xmmc\",\"type\":\"esriFieldTypeString\",\"alias\":\"xmmc\"},"
                        + "{\"name\":\"pzwh\",\"type\":\"esriFieldTypeString\",\"alias\":\"pzwh\"},"
                        + "{\"name\":\"htbh\",\"type\":\"esriFieldTypeString\",\"alias\":\"htbh\"},"
                        + "{\"name\":\"dkmj\",\"type\":\"esriFieldTypeDouble\",\"alias\":\"dkmj\"},"
                        + "{\"name\":\"bz\",\"type\":\"esriFieldTypeString\",\"alias\":\"bz\"}"
                        + "]";
                fieldInfos.Add("qxdm", "qxdm");
                fieldInfos.Add("jsscbh", "jsscbh");
                fieldInfos.Add("xmmc", "xmmc");
                fieldInfos.Add("pzwh", "pzwh");
                fieldInfos.Add("bz", "bz");
            }
            else if (ywtype == YwType.tdgy)
            {
                fields = "["
                        + "{\"name\":\"qxdm\",\"type\":\"esriFieldTypeString\",\"alias\":\"qxdm\"},"
                        + "{\"name\":\"jsscbh\",\"type\":\"esriFieldTypeString\",\"alias\":\"jsscbh\"},"
                        + "{\"name\":\"xmmc\",\"type\":\"esriFieldTypeString\",\"alias\":\"xmmc\"},"
                        + "{\"name\":\"dzjgh\",\"type\":\"esriFieldTypeString\",\"alias\":\"dzjgh\"},"
                        + "{\"name\":\"htbh\",\"type\":\"esriFieldTypeString\",\"alias\":\"htbh\"},"
                        + "{\"name\":\"dkmj\",\"type\":\"esriFieldTypeDouble\",\"alias\":\"dkmj\"},"
                        + "{\"name\":\"bz\",\"type\":\"esriFieldTypeString\",\"alias\":\"bz\"}"
                        + "]";

                fieldInfos.Add("qxdm", "qxdm");
                fieldInfos.Add("jsscbh", "jsscbh");
                fieldInfos.Add("xmmc", "xmmc");
                fieldInfos.Add("dzjgh", "dzjgh");
                fieldInfos.Add("bz", "bz");
            }
            else if (ywtype == YwType.tdgyql)
            {
                fields = "["
                        + "{\"name\":\"DZJGH\",\"type\":\"esriFieldTypeString\",\"alias\":\"DZJGH\"}"
                        + "]";

                fieldInfos.Add("bz", "bz");
            }
            else if (ywtype == YwType.tdcb)
            {
                fields = "["
                        + "{\"name\":\"qxdm\",\"type\":\"esriFieldTypeString\",\"alias\":\"qxdm\"},"
                        + "{\"name\":\"jsscbh\",\"type\":\"esriFieldTypeString\",\"alias\":\"jsscbh\"},"
                        + "{\"name\":\"xmmc\",\"type\":\"esriFieldTypeString\",\"alias\":\"xmmc\"},"
                        + "{\"name\":\"cbpwh\",\"type\":\"esriFieldTypeString\",\"alias\":\"cbpwh\"},"
                        + "{\"name\":\"htbh\",\"type\":\"esriFieldTypeString\",\"alias\":\"htbh\"},"
                        + "{\"name\":\"dkmj\",\"type\":\"esriFieldTypeDouble\",\"alias\":\"dkmj\"},"
                        + "{\"name\":\"bz\",\"type\":\"esriFieldTypeString\",\"alias\":\"bz\"}"
                        + "]";

                fieldInfos.Add("qxdm", "qxdm");
                fieldInfos.Add("jsscbh", "jsscbh");
                fieldInfos.Add("xmmc", "xmmc");
                fieldInfos.Add("cbpwh", "cbpwh");
                fieldInfos.Add("bz", "bz");
            }
            else if (ywtype == YwType.other)
            {
                fields = "["
                        + "{\"name\":\"qxdm\",\"type\":\"esriFieldTypeString\",\"alias\":\"qxdm\"},"
                        + "{\"name\":\"name\",\"type\":\"esriFieldTypeString\",\"alias\":\"name\"},"
                        + "{\"name\":\"type\",\"type\":\"esriFieldTypeString\",\"alias\":\"type\"},"
                        + "{\"name\":\"bz\",\"type\":\"esriFieldTypeString\",\"alias\":\"bz\"}"
                        + "]";

                fieldInfos.Add("qxdm", "qxdm");
                fieldInfos.Add("name", "name");
                fieldInfos.Add("bz", "bz");
            }

            Dictionary<String, Dictionary<String, HashSet<String>>> alldegreeResults = new Dictionary<String, Dictionary<String, HashSet<String>>>();

            //8-land转shp
            System.Console.WriteLine();
            System.Console.WriteLine("---------------第3步,Land对象生成SHP------------------");
            this.listBox1.Items.Add("  ");
            this.listBox1.Items.Add("---------------第3步,Land对象生成SHP------------------");
            //分度带18、35、36、37、cqdl进行转换
            Dictionary<String, Dictionary<String, Land>>.Enumerator degreeSet = allDegreeLands.GetEnumerator();
            while (degreeSet.MoveNext())
            {
                KeyValuePair<String, Dictionary<String, Land>> kvp = degreeSet.Current;
                String degree = kvp.Key;
                Dictionary<String, Land> degreeLand = kvp.Value;

                // 创建shape文件对象
                String shpname = "";
                String wkt = "";
                int  wkt_espg = 4524;
                if ("18" == degree)
                {
                    shpname = String.Format("{0}-shp18-{1}.shp", qxmc, tdgyfs);
                    wkt = wkt18;
                    wkt_espg = 4490;
                }
                else if ("35" == degree)
                {
                    shpname = String.Format("{0}-shp35-{1}.shp", qxmc, tdgyfs);
                    wkt = wkt35;
                    wkt_espg = 4523;
                }
                else if ("36" == degree)
                {
                    shpname = String.Format("{0}-shp36-{1}.shp", qxmc, tdgyfs);
                    wkt = wkt36;
                    wkt_espg = 4524;
                }
                else if ("37" == degree)
                {
                    shpname = String.Format("{0}-shp37-{1}.shp", qxmc, tdgyfs);
                    wkt = wkt37;
                    wkt_espg = 4525;
                }
                else if ("cqdl" == degree)
                {
                    //Beijing_1954_3_Degree_GK_CM_105E
                    shpname = String.Format("{0}-shpcqdl-{1}.shp", qxmc, tdgyfs);
                    wkt = wktcqdl;
                    wkt_espg = 2432;
                }
                else
                {
                    continue;
                }
                //SHP转换
                System.Console.WriteLine();
                System.Console.WriteLine(String.Format("正在处理第 {0} 度带的SHP转换-->输出文件地址:%s ", degree, shpname));
                this.listBox1.Items.Add(String.Format("正在处理第 {0} 度带的SHP转换-->输出文件地址:%s ", degree, shpname));
                Dictionary<String, HashSet<String>> res = null;
                /*
                res= LayerHelper.createShapefile3(
                        outpath,
                        shpname,
                        degreeLand,
                        wkt_espg,
                        fieldInfos, 
                        ywtype);
                */

                alldegreeResults.Add(degree, res);
                //shpfile文件全路径
                shpfileList.Add(outpath + "\\" + shpname);
            }

            //9-结果统计
            System.Console.WriteLine();
            System.Console.WriteLine();
            System.Console.WriteLine("---------------第4步, 数据处理结果统计------------------");
            this.listBox1.Items.Add("  ");
            this.listBox1.Items.Add("---------------第4步, 数据处理结果统计------------------");

            //投影的度带列表
            int numOfDegree = alldegreeResults.Count;
            Dictionary<String, Dictionary<String, HashSet<String>>>.Enumerator degreeKeySetEnumerator = alldegreeResults.GetEnumerator();
            System.Console.WriteLine(String.Format("--->一共包含：%d 个度带!  ", numOfDegree));
            while (degreeKeySetEnumerator.MoveNext())
            {
                //根据degree进行组织
                KeyValuePair<String, Dictionary<String, HashSet<String>>> kvp = degreeKeySetEnumerator.Current;
                String degree = kvp.Key;
                Dictionary<String, HashSet<String>> res = kvp.Value;

                HashSet<String> successSet = res["success"];
                HashSet<String> failSet = res["fail"];

                System.Console.WriteLine();
                System.Console.WriteLine(String.Format("--->度带：{0}, 成功:{1} 个数据， 失败:{2} 条数据  ", degree, successSet.Count, failSet.Count));

                //1-成功部分
                System.Console.WriteLine(String.Format("成功的DZJGH列表为："));
                HashSet<String>.Enumerator successIter = successSet.GetEnumerator();
                while (successIter.MoveNext())
                {
                    String dzjgh = successIter.Current;
                    System.Console.WriteLine(String.Format(" {0} ", dzjgh));
                }

                //2-失败部分
                System.Console.WriteLine(String.Format("失败的DZJGH列表为： "));
                HashSet<String>.Enumerator failIter = failSet.GetEnumerator();
                while (failIter.MoveNext())
                {
                    String dzjgh = failIter.Current;
                    System.Console.WriteLine(String.Format(" {0} ", dzjgh));
                }
            }
            System.Console.WriteLine();

            return shpfileList;
        }
    
    }
}
